package com.elinkway.infinitemovies.ui.activity.play;

import android.app.Activity;
import android.os.Handler;
import android.os.Message;
import android.view.View;
import android.webkit.WebSettings.PluginState;
import android.webkit.WebView;
import android.webkit.WebViewClient;

import com.elinkway.infinitemovies.ui.activity.play.SnifferJavascriptInterface.SnifferListener;
import com.elinkway.infinitemovies.utils.LogUtils;

import java.lang.reflect.InvocationTargetException;
import java.util.Arrays;
import java.util.List;
	
public class HTML5VideoSniffer implements SnifferListener{
	
	protected static final String TAG = "HTML5VideoSniffer";

	/**
	 * 嗅探脚本字串
	 * __Sniffer.logSrc(str);
	 */
	private final String SNIFFER_JS ="javascript:  (function _Hacked_getSrc() { var videos = document.getElementsByTagName(\"video\");" +
			"if(videos.length>0){"+
			"var video = videos[0];" +
			"video.setAttribute(\"preload\",\"none\");" +
			"if(!video.paused) {" +
			"	video.pause()" +
			"}" +
			"__Sniffer.logSrc(video.getAttribute(\"src\"));}" +
			"})();";
	
	private String mSnifferResult = null;

	/**
	 * MAX_FAILED_TIME
	 * 最大重试次数
	 */
	protected static final int MAX_FAILED_TIME =60;
	
	/**
	 * RETRY_TIMESPAN
	 * 重试间隔毫秒
	 */
	protected static final int RETRY_TIMESPAN =500;
	
	/**
	 * mHandler 枚举值 开始嗅探
	 */
	protected static final int RUN_JS = 0;
	
	private WebView mWebView;
	private Activity mContext;
	
	/**
	 * 重试计数
	 */
	private int mFailedCount = 1;
	/**
	 * 成功标识
	 */
	protected boolean  isSuccess = false;
	
	private boolean mIsTimeOut = false;
	
	/**
	 * 是否完成嗅探（无论成功success，失败failed，取消stop）,默认完成
	 */
	private boolean isComplete = true;
	
	
	
	/**
	 * mListener
	 * 嗅探回调
	 */
	private HTML5VideoSnifferListener mListener;
	
	/**
	 * mHandler
	 * 处理循环嗅探
	 */
	
	
	private Handler mHandler = new Handler(){

		@Override
		public void handleMessage(Message msg) {
			switch(msg.what) {
			case RUN_JS :
				LogUtils.e(TAG, "Sniffing in "+mFailedCount);
				runJavaScript(SNIFFER_JS);
				mFailedCount++;
				if(mFailedCount<=MAX_FAILED_TIME){
					sendEmptyMessageDelayed(RUN_JS, RETRY_TIMESPAN);
				}
				else{
					mIsTimeOut = true;
					onFailed();
				}
			}
			super.handleMessage(msg);
		}
		
	};

	/**
	 * 取消标识
	 */
	private boolean isCanceled = false;

	/**
	 * 嗅探页面 
	 */
	private String mUrl = "";

	private boolean isPaused = false;

	public HTML5VideoSniffer(Activity activity) {
		super();
		mWebView = new WebView(activity);
//		activity.addContentView(mWebView, new LayoutParams(1,1));
		mWebView.setVisibility(View.GONE);
		this.mContext=activity;
//		mWebView.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
		mWebView.getSettings().setBlockNetworkImage(true);
		mWebView.getSettings().setDomStorageEnabled(true);
		mWebView.getSettings().setPluginState(PluginState.OFF);

		mWebView.getSettings().setJavaScriptCanOpenWindowsAutomatically(false);
		mWebView.getSettings().setAllowFileAccess(false);
		mWebView.setWebViewClient(new WebViewClient(){

			@Override
			public void onReceivedError(WebView view, int errorCode,
					String description, String failingUrl) {
				onFailed();
				super.onReceivedError(view, errorCode, description, failingUrl);
			}
		});

		initWebView();
	}
	public HTML5VideoSniffer(WebView webView) {
		mWebView=webView;
		initWebView();
	}
	private void initWebView(){
		mWebView.getSettings().setJavaScriptEnabled(true);
		SnifferJavascriptInterface jsInterface = new SnifferJavascriptInterface(mContext);
		jsInterface.setmListener(this);
		mWebView.addJavascriptInterface(jsInterface, "__Sniffer");

	}

	protected void runJavaScript(String jscript) {
		// TODO Auto-generated method stub
		if(mWebView!=null&&!isCanceled ){
			mWebView.loadUrl(jscript);
		}
	}
	
	public interface HTML5VideoSnifferListener {
		void onSuccess(String url);
		void onFailed();
	}
	public void setSnifferListener(HTML5VideoSnifferListener mListener) {
		this.mListener = mListener;
	}
	
	/**
	 * 嗅探成功回调
	 * @param url
	 *  url 嗅探结果
	 */
	@Override
	public synchronized void onSuccess(String url) {
		if(!isSuccess){
    		LogUtils.i(TAG, "sniffer success");
    		LogUtils.i(TAG, url);
    		mSnifferResult = url;
			isSuccess=true;
			isComplete=true;
			mHandler.removeMessages(RUN_JS);
			mHandler.post(new Runnable() {
				@Override
				public void run() {
		    		LogUtils.i(TAG, "clear webview");
		    		mWebView.stopLoading();
				    mWebView.loadUrl("about:blank");
				    mWebView.freeMemory();
				}
			});
			if(mListener!=null&&!isCanceled){
				mListener.onSuccess(url);
			}
		}
	}
	public void stop() {
		isCanceled=true;
		mHandler.removeMessages(RUN_JS);
		isComplete=true;
	}
	
	/**
	 * 嗅探失败回调
	 */
	private void onFailed() {
		LogUtils.e(TAG, "sniffer failed");
		mHandler.removeMessages(RUN_JS);
		isComplete = true;
		if(mListener!=null&&!isCanceled){
			mListener.onFailed();
		}
	}
	public void destroy(){
			mHandler.removeMessages(RUN_JS);
			isCanceled=true;
			isComplete=true;
		    mWebView.loadUrl("about:blank");
		    mWebView.freeMemory();
		    mWebView.removeAllViews();
		    mWebView.destroy();
		    mWebView = null;
	}
	
	public void onPause(){
		try {
			if(!isPaused) {
				isPaused=true;
				mHandler.removeMessages(RUN_JS);
				if(null != mWebView) {
					mWebView.getClass().getMethod("onPause")
					.invoke(mWebView, (Object[]) null);
				    mWebView.pauseTimers(); //new code
				}
			}
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		} catch (IllegalArgumentException e) {
			e.printStackTrace();
		} catch (InvocationTargetException e) {
			e.printStackTrace();
		} catch (NoSuchMethodException e) {
			e.printStackTrace();
		}catch(Exception e) {
			e.printStackTrace();
		}
	}

	public void onResume() {
		try {
			if(isPaused) {
				isPaused=false;
				mWebView.getClass().getMethod("onResume")
						.invoke(mWebView, (Object[]) null);
				mWebView.resumeTimers(); // new code
				if (!isComplete) {
					mHandler.sendEmptyMessageDelayed(RUN_JS, RETRY_TIMESPAN);
				}
			}
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		} catch (IllegalArgumentException e) {
			e.printStackTrace();
		} catch (InvocationTargetException e) {
			e.printStackTrace();
		} catch (NoSuchMethodException e) {
			e.printStackTrace();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	/**
	 * 执行嗅探
	 * @param url
	 */
	public void run(String url,String site){
		mWebView.loadUrl("about:blank");
		if(validateSite(site)){
			mUrl=url;
			isSuccess=false;
			isCanceled=false;
			mIsTimeOut = false;
			isComplete = false;
			mFailedCount=0;
			mWebView.loadUrl(url);
			mHandler.sendEmptyMessageDelayed(RUN_JS,RETRY_TIMESPAN);
		}
		else {
			mIsTimeOut = true;
			if (mListener!=null) {
				mListener.onFailed();
			}
		}
	}
	private boolean validateSite(String site) {
		final String [] unsupport = {"youku", "tudou", "letv","qq"};
	    List<String> tempList = Arrays.asList(unsupport);
	    return !(tempList.contains(site.toLowerCase()));
	}
	public boolean ismIsTimeOut() {
		return mIsTimeOut;
	}
	
	public String getmSnifferResult() {
		return mSnifferResult;
	}
	
	public void setmSnifferResult(String mSnifferResult) {
		this.mSnifferResult = mSnifferResult;
	}
    
	public void setmIsTimeOut(boolean mIsTimeOut) {
		this.mIsTimeOut = mIsTimeOut;
	}
}
